﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;

namespace LogonDesktopTools
{
    static class Program
    {
        static string desktop_name = "Default";
        static EventLog eventLog = null;
        static int event_id = 0;
        static ManualResetEvent thread_exit_event = new ManualResetEvent(false);
        static IntPtr desktop_foreground_window = IntPtr.Zero;

        public static string DesktopName { get { return desktop_name; } }

        public static IntPtr DesktopForegroundWindow { get { return desktop_foreground_window; } }

        public static void Log(string message, EventLogEntryType type)
        {
            eventLog.WriteEntry(message, type, event_id++);
        }

        public static void Log(string message)
        {
            Log(message, EventLogEntryType.Information);
        }

        static void OnThread(object input_desktop)
        {
            if (WinApi.SetThreadDesktop((IntPtr)input_desktop))
            {
                desktop_foreground_window = WinApi.GetForegroundWindow();
                Log("desktop foreground window " + desktop_foreground_window);
                ToolsForm form = new ToolsForm();
                form.Show(null);
                Application.Run(form);
            }
            else Log("SetThreadDesktop failed with error " + Marshal.GetLastWin32Error(), EventLogEntryType.Error);
            thread_exit_event.Set();
        }

        [STAThread]
        static void Main(string[] args)
        {
            eventLog = new EventLog();
            eventLog.Log = eventLog.Source = "Logon Desktop Tools";

            Log("process started");

            if (args.Length > 0)
                desktop_name = args[0];

            while (true)
            {
                IntPtr input_desktop = WinApi.OpenInputDesktop(0, false, WinApi.GENERIC_ALL);
                if (IntPtr.Zero != input_desktop)
                {
                    byte[] input_desktop_name_buffer = new byte[WinApi.MAX_PATH];
                    UInt32 size = 0;
                    if (WinApi.GetUserObjectInformation(input_desktop, WinApi.UOI_NAME, input_desktop_name_buffer, WinApi.MAX_PATH, out size))
                    {
                        string input_desktop_name = Encoding.ASCII.GetString(input_desktop_name_buffer);
                        if (0 == string.Compare(desktop_name, input_desktop_name, true))
                        {
                            Log("switched to " + desktop_name + " desktop");
                            Thread thread = new Thread(new ParameterizedThreadStart(OnThread));
                            thread.SetApartmentState(ApartmentState.STA);
                            thread.Start(input_desktop);
                            thread_exit_event.WaitOne();
                            break;
                        }
                    }
                    WinApi.CloseDesktop(input_desktop);
                }
                Thread.Sleep(TimeSpan.FromMilliseconds(500));
            }
            Log("process stopped");
        }
    }
}
